#pragma once

#include "Team.h"
#include "Classification.h"
#include "Calendar.h"
#include "Serializable.h"
#include "LeagueSettings.h"

#include <vector>

class ServiceProvider;

class League : public Serializable
{
public:
	
	League(ServiceProvider* i_sp);
	~League();

	void Clear();
	void Initialize(std::string& name, LeagueSettings& i_settings); 
	void Update(const bool i_doNotPrompt);
	bool IsEnded() const;
	void EndSeasonUpdate(const bool i_doNotPrompt, std::stringstream& o_message);

	const Calendar*	GetCalendar() const;
	const Classification* GetClassification() const;
	const TeamVec& GetTeams() const;
	TeamVec& GetTeams();
	const MatchVec& GetLastPlayedTurn() const;
	const std::string& GetName() const;
	const LeagueSettings& GetSettings() const;
	int GetNumPromoted() const;
	int GetNumDemoted() const;

	/**
		Return the index of this team in the sorted classification (0 is the top)
		if the team isn't into the container return -1
	*/
	int GetTeamPosition(Team const * const i_team);

	/**
		This method invalid the calendar so also the league itself
		You MUST call Restart to re-init the league	
	*/
	void ChangeTeam(Team* i_oldTeam, Team* i_newTeam); 

	/**
		function that "swap" the last [team_num] teams from this league
		with the first [team_num] teams from [o_league].
	*/
	void SwapLastFirstTeam(League& o_league, const size_t team_num);

	//da commentare bene
	bool RemoveFirstOrLastTeams(TeamVec& o_removed, size_t i_numToRemove, bool i_removeFromEnd = true);
	
	int GetLayerIndex() const;

	virtual	ZStream& Serialize(ZStream& o_stream);
	virtual ZStream& Deserialize(ZStream& i_stream);

	static const int	MAX_LEAGUE_NAME_SIZE = 15;

private:
	void				Restart();

	std::string			m_leagueName;
	LeagueSettings		m_settings;
	TeamVec				m_teams;
	Classification		m_classification;
	Calendar			m_calendar;
	MatchVec		m_lastPlayedTurn;
	ServiceProvider*	m_sp;
};

inline const Calendar* League::GetCalendar() const
{
	return &m_calendar;
}

inline const Classification* League::GetClassification() const
{
	return &m_classification;
}

inline const TeamVec& League::GetTeams() const
{
	return m_teams;
}

inline TeamVec& League::GetTeams()
{
	return m_teams;
}

inline const MatchVec& League::GetLastPlayedTurn() const
{
	return m_lastPlayedTurn;
}

inline const std::string& League::GetName() const
{
	return m_leagueName;
}

inline const LeagueSettings& League::GetSettings() const
{
	return m_settings;
}

inline int League::GetLayerIndex() const
{
	return m_settings.layerIndex;
}
